home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / text / edit / tecoc-146.lha / exeo.c < prev    next >
C/C++ Source or Header  |  1991-07-05  |  5KB  |  196 lines

  1. /*****************************************************************************
  2.  
  3.     ExeO()
  4.  
  5.     This function executes an O command.
  6.     Otag        Goto label
  7.     nOtag0,tag1    Computed goto
  8. *****************************************************************************/
  9.  
  10. #include "zport.h"        /* define portability identifiers */
  11. #include "tecoc.h"        /* define general identifiers */
  12. #include "defext.h"        /* define external global variables */
  13. #include "dchars.h"        /* define identifiers for characters */
  14. #include "deferr.h"        /* define identifiers for error messages */
  15.  
  16. DEFAULT ExeO()            /* execute an O command */
  17. {
  18.     BOOLEAN Found;        /* has the tag been found? */
  19.     unsigned char TBfBeg[TBFINIT]; /* tag buffer */
  20.     charptr TBfEnd;        /* end of tag buffer */
  21.     charptr TBfPtr;        /* end of tag in tag buffer */
  22.     charptr TagPtr;        /* pointer into tag buffer */
  23.     charptr TmpPtr;        /* temp pointer for shuffling in Tbf */
  24.  
  25.     DBGFEN(1,"ExeO",NULL);
  26.  
  27.     /*
  28.      * ??? Pete,
  29.      * given "O^EQq$" we simply use BldStr to build the string
  30.      * before looking for the tag in q-reg q.  What do we do if
  31.      * given "nOtag0,^EQq,tag2$", especially if q-reg q contains a
  32.      * comma?  if we BldStr first, the comma in the q-reg will
  33.      * change the number of tags, maybe changing the nth tag.
  34.      * If we BldStr after finding the tag we want, we don't take
  35.      * into account the list of tags which may be in q-reg q.
  36.      *
  37.      * After implementing it the second way (search/Bldstr), I find
  38.      * it is much easier to do it the first way (BldStr/search).  One
  39.      * disadvantage to doing it this way is BldStr is probably building
  40.      * much more than it needs to, potentially overrunning TBf?
  41.      */
  42.  
  43.     TBfEnd = TBfBeg + TBFINIT;
  44.     if (BldStr(TBfBeg, TBfEnd, &TBfPtr) == FAILURE) {
  45.     DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
  46.     return FAILURE;
  47.     }
  48.  
  49. /*
  50.  * If there's something on the expression stack, then we have a computed
  51.  * goto, so figure out which tag in TBf they want.
  52.  *
  53.  *        TBf:    "TAG0,TAG1,TAG2........"
  54.  *             ^             ^       ^
  55.  *             TBfBeg        TBfPtr  TBfEnd
  56.  */
  57.  
  58.     if (EStTop > EStBot) {
  59.     if (GetNmA () == FAILURE) {    /* get NArgmt */
  60.         DBGFEX(1,DbgFNm,"FAILURE, GetNmA() failed");
  61.         return FAILURE;
  62.     }
  63.     if (NArgmt < 0) {        /* n is out of range */
  64.         TagPtr = TBfPtr;        /* say we ran into end of tag list */
  65.     } else {            /* find the nth tag */
  66.         TagPtr = TBfBeg;
  67.         if (NArgmt > 0) {        /* n==0 is already done */
  68.         while (TagPtr < TBfPtr) {
  69.             if (*TagPtr++ == ',') {
  70.             if (--NArgmt == 0) {
  71.                 break;
  72.             }
  73.             }
  74.         }
  75.         }
  76.     }
  77.  
  78. /*
  79.  * If we ran into the end of the tag list, or the tag we found is null
  80.  * (",,"), then flow past nO command.
  81.  */
  82.  
  83.     if (TagPtr == TBfPtr || *TagPtr == ',') {
  84.         DBGFEX(1,DbgFNm,"SUCCESS");
  85.         CmdMod = '\0';            /* clear modifiers flags */
  86.         return SUCCESS;
  87.     }
  88.  
  89. /*
  90.  * shuffle tag we found to beginning of TBf for searching.
  91.  */
  92.  
  93.     TmpPtr = TBfBeg;
  94.     while (TagPtr < TBfPtr && *TagPtr != ',') {
  95.         *TmpPtr++ = *TagPtr++;
  96.     }
  97.     TBfPtr = TmpPtr;
  98.     }
  99.  
  100. #if DEBUGGING
  101.     *TBfPtr = '\0';
  102.     sprintf(DbgSBf,"searching for tag \"%s\"", TBfBeg);
  103.     DbgFMs(1,DbgFNm,DbgSBf);
  104. #endif
  105.  
  106. /*
  107.  * reset CBfPtr to point to the front of the command string,  or the front
  108.  * of the loop if we're in a loop, then search for the tag in TBf, keeping
  109.  * track of nested <> loops.
  110.  */
  111.  
  112.     CBfPtr = (LStTop == LStBot) ? CStBeg : LStack[LStTop].LAddr + 1;
  113.     Found = FALSE;
  114.     CmdMod = '\0';                /* clear modifiers flags */
  115.     while (!Found) {
  116.     while (*CBfPtr != '!') {
  117.         if (CBfPtr == CStEnd) {
  118.         ErrPSt(ERR_TAG, TBfBeg, TBfPtr);
  119.         DBGFEX(1,DbgFNm,"FAILURE, missing tag");
  120.         return FAILURE;
  121.         }
  122.         switch (*CBfPtr) {
  123.         case '<':
  124.         if (++LStTop >= LPS_SIZE) {
  125.             ErrMsg(ERR_PDO);
  126.             DBGFEX(1,DbgFNm,"FAILURE");
  127.             return FAILURE;
  128.         }
  129.         LStack[LStTop].LIndex = INFINITE;
  130.         LStack[LStTop].LAddr = CBfPtr;
  131.         CmdMod = '\0';
  132.         break;
  133.  
  134.         case '>':
  135.         if (LStTop == LStBot) {
  136.             ErrMsg(ERR_BNI);
  137.             DBGFEX(1,DbgFNm,"FAILURE");
  138.             return FAILURE;
  139.         }
  140.         --LStTop;
  141.         CmdMod = '\0';
  142.         break;
  143.  
  144.         default:
  145.         if (SkpCmd() == FAILURE) {
  146.             DBGFEX(1,DbgFNm,"FAILURE, SkpCmd() failed");
  147.             return FAILURE;
  148.         }
  149.         } /* end of switch */
  150.         ++CBfPtr;
  151.     } /* end of while (!='!')*/
  152.  
  153. /*
  154.  * At this point, we've found an '!'.  if tracing is on,  display exclamation
  155.  * point
  156.  */
  157.  
  158.     if (TraceM) {                /* if trace mode is on */
  159.         if (CmdMod & ATSIGN) {        /* if it was @O */
  160.         ZDspCh('@');
  161.         }
  162.         ZDspCh('!');
  163.     }
  164.  
  165.     if (FindES('!') == FAILURE) {    /* find end of tag */
  166.         DBGFEX(1,DbgFNm,"FAILURE, FindES() failed");
  167.         return FAILURE;
  168.     }
  169.  
  170. #if DEBUGGING
  171.     sprintf(DbgSBf,"found tag \"%.*s\"\n",(int)(CBfPtr-ArgPtr), ArgPtr);
  172.     DbgFMs(1,DbgFNm,DbgSBf);
  173. #endif
  174.  
  175. /*
  176.  * compare found tag (in ArgPtr) to O command tag (in TBf).
  177.  */
  178.  
  179.     TagPtr = TBfBeg;
  180.     while ((TagPtr < TBfPtr) && (*ArgPtr == *TagPtr)) {
  181.         ++ArgPtr;
  182.         ++TagPtr;
  183.     }
  184.     Found = ((TagPtr == TBfPtr) && (*ArgPtr == '!'));
  185.  
  186.     ++CBfPtr;
  187.     } /* end of while (!Found) */
  188.  
  189.     --CBfPtr;
  190.     CmdMod = '\0';                /* clear modifiers flags */
  191.  
  192.     DBGFEX(1,DbgFNm,"SUCCESS");
  193.  
  194.     return SUCCESS;
  195. }
  196.